
//  CAIDBManager.h
//  Runner
//
//  Created by simon on 2021/8/31.
//

#import <Foundation/Foundation.h>
#import "CAIFileCache.h"
#import "CAIFMDB.h"

NS_ASSUME_NONNULL_BEGIN

@interface CAIStorageManager : NSObject


/// 始终使用initWithName:初始化的对象并返回；
+ (instancetype)sharedInstance;


/// 初始化对象，并指定使用Archive的方式同步存储对象的时候的文件路径；默认是NSDocumentDirectory路径；
/// @param name 文件夹名称
- (instancetype)initWithName:(nullable NSString *)name;


/// 初始化对象，并指定使用Archive的方式同步存储对象的时候的文件路径；
/// @param name 文件夹名称
/// @param rootPath 文件夹根路径
- (instancetype)initWithName:(nullable NSString *)name rootPath:(NSString *)rootPath;

/**
 *  以NSUserDefault方式同步存对象，PList对象定义如下：
 *  NSNumber、NSString、NSData、NSDate、NSArray、NSDictionary，NSArray和NSDictionary;且他们的子对象也只能是Property List对象。对于超过150Kb的数据，会兜底用archive方式存储；
 */
- (void)setObject:(id)object forKey:(NSString *)key;

/**
 *  以NSUserDefault方式加密存对象;同上；
 *  如果setObject:forKey和setEncodeCryptObject:forKey:error使用同一个key，会覆盖存储；
 *
 */
- (void)setEncodeCryptObject:(id)object
                      forKey:(NSString *)key
                       error:(NSError * __autoreleasing *)error;


/**
 *  使用Archive的方式同步存储对象，只要对象支持NSCoding，都可以归档。
 *  Property List对象也可以使用archive方式归档，但速度要慢很多，建议当对象肯定为Property List时，使用setObject方法。主要用于序列化存储不支持的对象,复杂对象图对象；
 */
- (void)archiveObject:(id <NSCoding>)object forKey:(NSString *)key;



/// 加密存对象；同上；
/// @param object 根对象
/// @param key key
/// @param error 错误信息
- (void)archiveEncodeCryptObject:(id <NSSecureCoding>)object
                          forKey:(NSString *)key
                           error:(NSError * __autoreleasing *)error;

/**
 *  同步取对象；业务层不需要关心归档/序列化方式，统一使用该接口取对象。
 */
- (id)objectForKey:(NSString *)key;

/**
 *  同步取对象，用于解密的。业务层不需要关心归档/序列化方式，需解密的统一使用该接口取对象。
 *  cls:解密返回的根对象类
 */
- (id)objectDecodeCryptForKey:(NSString *)key
                expectedClass:(Class)cls
                        error:(NSError * __autoreleasing *)error;

/**
 *  同步删除对象，业务层不需要关心归档/序列化方式，统一使用该接口删除对象。
 */
- (void)removeObjectForKey:(NSString *)key;



//////////////数据库方式//////////////


/// 设置：把model模型按json数据字符串插入;一个表只能插入一个数据；会自动创建检查表，如果已经有数据则update更新，如果没有数据则inset插入；
/// @param tableName 表的名称
/// @param model 模型对象，
/// @param error 错误信息
- (BOOL)setTable:(NSString *)tableName
           model:(id)model
           error:(NSError * __autoreleasing *)error;


/// 设置：加密方式把model模型按json数据字符串插入;一个表只能插入一个数据；会自动创建检查表，如果已经有数据则update更新，如果没有数据则inset插入；
/// @param tableName 表的名称
/// @param model 模型对象，
/// @param error 错误信息
- (BOOL)setEncodeWithTable:(NSString *)tableName
                     model:(id)model
                     error:(NSError * __autoreleasing *)error;
/**
 查找:查找表中数据

 @param tableName 表的名称
 @param cls 模型名
 @return 返回原数据
 */
- (id)fetchTable:(NSString *)tableName modelClass:(Class)cls;

/// 查找:加密方式查找表中数据
/// @param tableName 表的名称
/// @param cls 模型名
- (id)fetchDecodeWithTable:(NSString *)tableName modelClass:(Class)cls;


/// 删除表
/// @param tableName 表的名称
- (BOOL)dropTable:(NSString *)tableName;


@end

NS_ASSUME_NONNULL_END
